package shopping

import (
	"dhfshop/service/event"
	"time"
	"dhfshop/models/shopping"
	"encoding/json"
	"dhfshop/models/misc"
	"dhfshop/models/org"
	"github.com/astaxie/beego/validation"
	"dhfshop/controllers/base"
	"dhfshop/models"
	"github.com/looplab/fsm"
	"github.com/astaxie/beego"
)


func ReturnEventInit() {
	event.KernelBus.Subscribe("R_EVENT_REVIEW_REQ",ReturnFsm)
	event.KernelBus.Subscribe("R_EVENT_SETTLE_REQ",ReturnFsm)
	event.KernelBus.Subscribe("R_EVENT_FINISH_REQ",ReturnFsm)
	event.KernelBus.Subscribe("R_EVENT_INVALID_REQ",ReturnFsm)
}

func ReturnFsm(message string, out *string) {
	var msg event.ReturnMsg
	if result, err := event.DecodeMsg(message, &msg); err != nil {
	    beego.Debug("result:", result)
		*out = err.Error()
		return
	}
	o := models.GetDefaultDB()
	pReturnForm := &shopping.ReturnForm{}
	err := o.QueryTable(new(shopping.ReturnForm)).Filter("company_id",msg.CompanyId).Filter("return_form_id",msg.ReturnFormId).One(pReturnForm,"status")
	if err != nil {
	    *out = err.Error()
		return
	}
	curState := pReturnForm.Status
	returnform := fsm.NewFSM(
	  curState,
	  fsm.Events{
		{Name: "R_EVENT_REVIEW_REQ", Src: []string{"R_ALREADY_CREATED"}, Dst: "R_REVIEW_FINISH"},
		{Name: "R_EVENT_SETTLE_REQ", Src: []string{"R_REVIEW_FINISH"}, Dst: "R_ALREADY_SETTLE"},
		{Name: "R_EVENT_FINISH_REQ", Src: []string{"R_ALREADY_SETTLE"}, Dst: "R_ALREADY_FINISH"},
		{Name: "R_EVENT_INVALID_REQ", Src: []string{"R_ALREADY_CREATED"}, Dst: "R_ALREADY_INVALID"},
	  },
	  fsm.Callbacks{},      //不需要回调打印
	)
	err = returnform.Event(msg.MsgHeader.EventType)
	if err != nil {
	    *out = err.Error()
		return
	}
	nextState := returnform.Current()
	pReturnForm.ReturnFormId = msg.ReturnFormId
	pReturnForm.Status = nextState
	_, err = o.Update(pReturnForm,"status")
	if err != nil {
	    *out = err.Error()
		return
	}
	return
}

type ReturnController struct {
	base.BaseController
}

func (this *ReturnController) List() {
	query,_,fields,order_by,offset,limit,err := this.GetQueryPara()
	if err != nil {
	   this.ServeError(err.Error())
	   return
	}
	l, cnt, err := shopping.GetAllReturnForms(query,fields,order_by,offset,limit)
	if err != nil {
	    this.ServeError(err.Error())
	    return
	}
		r := struct {
		    TotalCount   int64                 `json:"total_count"`
	        ReturnForm  []*shopping.ReturnForm `json:"return_forms"`
	    }{TotalCount: cnt, ReturnForm: l}
	    this.Data["json"] = r
	this.ServeJSON()
}

func (this *ReturnController) Post() {
	var v shopping.ReturnForm
	valid := validation.Validation{}
	this.ParseForm(&v)
	curUserId := this.Ctx.Input.GetData("curCompanyId").(int)
	v.PartnerId = int64(curUserId)
	v.CreatorId = int64(curUserId)
	passed, _ := valid.Valid(&v)
	if !passed {
		this.ServeError(valid.Errors[0].Key+" "+valid.Errors[0].Message)
		return	
	}
    v.CreatorUser, _= org.GetUserByUserId(v.CreatorId)
	v.ReturnFormId, _ = misc.GetBillNo("RF")
	v.Status = "R_ALREADY_CREATED"
	if len(v.InItemJson) > 10 {
	    err := json.Unmarshal([]byte(v.InItemJson), &v)
	    if err != nil {
	        this.ServeError(err.Error())
            return
	    }
		for _, initem := range v.InItems {
		    initem.ReturnForm = &v               // pay more attention
		    initem.PartnerId = v.PartnerId
	    }
	    v.TypeId =  v.TypeId | 8
	}
	if len(v.OutItemJson) > 10 {
	    err := json.Unmarshal([]byte(v.OutItemJson), &v)
	    if err != nil {
	        this.ServeError(err.Error())
            return
	    }
		for _, outitem := range v.OutItems {
		    outitem.ReturnForm = &v               // pay more attention
		    outitem.PartnerId = v.PartnerId
	    }
	    v.TypeId =  v.TypeId | 4
	}
	_, err := shopping.AddReturnForm(&v);
	if err != nil {
       this.ServeError(err.Error())
		return
    }
	if len(v.InItems) > 0 {
	    if err := shopping.AddReturnFormItems(v.InItems); err != nil {
		    this.ServeError(err.Error())
            return
	    }
	}
	if len(v.OutItems) > 0 {
	    if err := shopping.AddReplaceFormItems(v.OutItems); err != nil {
		    this.ServeError(err.Error())
            return
	    }
	}
	rsp := struct {
		ReturnFormId string        `json:"return_form_id"`
	    Created      time.Time    `json:"created"`
	}{ReturnFormId: v.ReturnFormId, Created:time.Now().UTC()}
	this.Data["json"] = rsp
	this.ServeJSON()
}


func (this *ReturnController) Put() {
	/*
	v := shopping.ReturnForm{}
	this.ParseForm(&v)
	v.PartnerId = int64(this.Ctx.Input.GetData("curCompanyId").(int))
    //curUserId := this.Ctx.Input.GetData("curUserId").(int)
	valid := validation.Validation{}
	passed, _ := valid.Valid(&v)
	if !passed {
		this.ServeError(valid.Errors[0].Key+" "+valid.Errors[0].Message)
		return 
	}
	updateFields, err := this.GetUpdateFields(v, "", "form", []string{""})
	if err != nil {
	    this.ServeError(err.Error())
		return
	}
	if err := shopping.UpdateReturnFormById(&v, updateFields...); err != nil{
		this.ServeError(err.Error())
		return
	}
	if len(v.InItemJson) > 10 {
        subUpdateFields, err := helper.GetSubUpdateFields(v.InItemJson, consts.UpdateReturnItemFeilds)
	    if err != nil {
	       this.ServeError(err.Error())
		    return
	    }
		 if len(subUpdateFields) > 0 {
	        err = json.Unmarshal([]byte(v.InItemJson), &v)
	        if err != nil {
		      this.ServeError(err.Error())
		        return
	        }
	        for _, in := range v.InItems {
	            in.ReturnForm = &v               // pay more attention
	   	        if in.ReturnItemId > 0 {
				    if err := shopping.UpdateReturnFormItemById(in, subUpdateFields...); err != nil {
		              this.ServeError(err.Error())
                        return 			
	                }
				}else{
				    if _,err := shopping.AddReturnFormItem(in); err != nil {
		                this.ServeError(err.Error())
                        return 			
	                }
				}	
	        }
	    }	
	}
	if len(v.OutItemJson) > 10 {
        subUpdateFields, err := helper.GetSubUpdateFields(v.OutItemJson, consts.UpdateReturnItemFeilds)
	    if err != nil {
	        this.ServeError(err.Error())
		    return
	    }
		 if len(subUpdateFields) > 0 {
	        err = json.Unmarshal([]byte(v.OutItemJson), &v)
	        if err != nil {
		     this.ServeError(err.Error())
		        return
	        }
	        for _, out := range v.OutItems {
	            out.ReturnForm = &v               // pay more attention
	   	        if out.ReplaceItemId > 0 {
				    if err := shopping.UpdateReplaceFormItemById(out, subUpdateFields...); err != nil {
		               this.ServeError(err.Error())
                        return 			
	                }
				}else{
				    if _, err := shopping.AddReplaceFormItem(out); err != nil {
		               this.ServeError(err.Error())
                        return 			
	                }
				}	
	        }
	    }	
	}
	rsp := struct {
		    ReturnFormId  string       `json:"return_form_id"`
	        Modified      time.Time   `json:"modified"`
	    }{ReturnFormId:v.ReturnFormId, Modified:time.Now().UTC()}
	this.Data["json"] = rsp
	this.ServeJSON()
	*/
}


func (this *ReturnController) StatusUpdate() {
	companyId := int64(this.Ctx.Input.GetData("curCompanyId").(int))
	//curUserId := this.Ctx.Input.GetData("curUserId").(int)
	v := struct {
		CompanyId    int64      `form:"-"  valid:"Required"`
	    ReturnFormId string   `form:"return_form_id" valid:"Required"`
		Event        string   `form:"event" valid:"Required"`
		Remark       string   `form:"remark"`
	}{CompanyId: companyId} 
	this.ParseForm(&v)
	valid := validation.Validation{}
	passed, _ := valid.Valid(&v)
	if !passed {
		this.ServeError(valid.Errors[0].Key+" "+valid.Errors[0].Message)
		return 
	}
	/*
	mReturnForm, err := shopping.GetReturnFormById(v.ReturnFormId)
	if err != nil {
	    this.ServeError(err.Error())
		return
	}
	*/
	/**************************
	 *  1. 入库商品           *
     *  2. 出库商品           *
     *  3. 商家给顾客补偿钱   *
     *  4. 顾客给商家补偿钱   *
	***************************/
	//event.ReturnBus.Publish(v.Event,message,&result)
	rsp := struct {
		ReturnFormId  string      `json:"return_form_id"`
	    Modified      time.Time   `json:"modified"`
	}{ReturnFormId:v.ReturnFormId, Modified:time.Now().UTC()}
	this.Data["json"] = rsp
	this.ServeJSON()	
}

func (this *ReturnController) Delete() {
    //companyId := this.Ctx.Input.GetData("curCompanyId").(int)
    //curUserId := this.Ctx.Input.GetData("curUserId").(int)
	returnFormId := this.GetString("return_form_id")
	if returnFormId == "" {
		this.ServeError("return_form_id is null")
		return 
	}
	mReturnForm, err := shopping.GetReturnFormById(returnFormId)
	if err != nil {
	    this.ServeError(err.Error())
		return
	}
	if mReturnForm.Status != "R_ALREADY_CREATED" {
		this.ServeError("state is invalid")
	    return
	}
	mReturnForm.Status = "R_ALREADY_INVALID"
	if err := shopping.UpdateReturnFormById(mReturnForm,"status"); err != nil{
		this.ServeError(err.Error())
		return
	}
	rsp := struct {
		ReturnFormId  string      `json:"return_form_id"`
	    Modified      time.Time   `json:"modified"`
	}{ReturnFormId:returnFormId, Modified:time.Now().UTC()}
	this.Data["json"] = rsp
	this.ServeJSON()
}
